﻿//-----------------------------------------------------------------------
// <copyright file="FileManager.cs" company="Paul V. Borza">
// http://fastget.codeplex.com/license
// </copyright>
//-----------------------------------------------------------------------

namespace FastGet
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Text;

    internal static class FileManager
    {
        public static HashSet<string> ReadCache(string filePath)
        {
            var set = new HashSet<string>();

            if (File.Exists(filePath))
            {
                foreach (var line in File.ReadAllLines(filePath))
                {
                    set.Add(line);
                }
            }

            return set;
        }

        public static Queue<HttpWebRequest> Read(string filePath, ref long filePosition, int iterationCount, int bucketSize, int timeout)
        {
            var queue = new Queue<HttpWebRequest>();

            var bytes = filePosition;
            var i = 0;

            using (var reader = new StreamReader(filePath))
            {
                reader.BaseStream.Seek(filePosition, SeekOrigin.Begin);

                while (i < bucketSize && !reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    // Console.WriteLine(line);

                    // will break if it's not a proper \r\n new line
                    bytes += Encoding.ASCII.GetByteCount(line) + Encoding.ASCII.GetByteCount(Environment.NewLine);

                    for (var j = 0; j < iterationCount; j++)
                    {
                        var request = Parse(line, timeout);

                        queue.Enqueue(request);
                    }

                    i++;
                }

                if (!reader.EndOfStream)
                {
                    filePosition = bytes;
                }
                else
                {
                    filePosition = -1;
                }
            }

            return queue;
        }

        private static HttpWebRequest Parse(string line, int timeout)
        {
            if (line == null)
            {
                throw new ArgumentNullException("line");
            }

            var url = string.Empty;
            var method = string.Empty;
            var body = string.Empty;
            var headers = new List<string>();

            var quoteStarted = false;
            var previousIndex = 0;

            for (var i = 0; i <= line.Length; i++)
            {
                quoteStarted ^= (i < line.Length && line[i] == '"');

                if ((i < line.Length && line[i] == ' ' && !quoteStarted) || i == line.Length)
                {
                    var arg = line.Substring(previousIndex, i - previousIndex);

                    if (arg.StartsWith("-url:", StringComparison.OrdinalIgnoreCase))
                    {
                        // -path:http://www.borza.ro/
                        url = arg.Substring("-url:".Length);
                    }
                    else if (arg.StartsWith("-method:", StringComparison.OrdinalIgnoreCase))
                    {
                        // -method:GET
                        method = arg.Substring("-method:".Length);
                    }
                    else if (arg.StartsWith("-body:", StringComparison.OrdinalIgnoreCase))
                    {
                        // -body:name=abc&address=def
                        body = arg.Substring("-body:".Length);
                    }
                    else if (arg.StartsWith("-header:", StringComparison.OrdinalIgnoreCase))
                    {
                        var header = arg.Substring("-header:".Length);

                        headers.Add(header);
                    }

                    // skips the current space character
                    previousIndex = i + 1;
                }
            }

            var request = (HttpWebRequest)WebRequest.Create(url);

            // sets the header so that the connection is persisted to the host
            request.KeepAlive = true;
            request.Method = method;
            request.Timeout = timeout;
            //// request.ReadWriteTimeout = timeout;

            if (!string.IsNullOrEmpty(body))
            {
                using (var writer = new StreamWriter(request.GetRequestStream()))
                {
                    writer.Write(body);
                }
            }

            foreach (var header in headers)
            {
                if (header.StartsWith("Content-Type:", StringComparison.OrdinalIgnoreCase))
                {
                    request.ContentType = header.Substring("Content-Type:".Length);
                }
                else
                {
                    request.Headers.Add(header);
                }
            }

            return request;
        }
    }
}
